package com.jvyou.driver.resolver;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jvyou.driver.auth.LoginRequest;
import com.jvyou.driver.auth.LoginType;
import com.jvyou.driver.auth.UserCredential;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.stream.Collectors;

/**
 * 登录请求体解析器，用于判断登录类型，并自动填充登录类型
 *
 * @author 橘柚
 * @since 2024/12/14 10:06
 */
@Component
public class LoginRequestResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 判断是否有 @LoginRequest 注解
        return parameter.hasParameterAnnotation(LoginRequest.class) &&
                parameter.getParameterType().equals(UserCredential.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception {

        // 从请求中读取 JSON 数据
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

        // 解析 JSON 数据
        ObjectMapper objectMapper = new ObjectMapper();
        UserCredential userCredential = objectMapper.readValue(body, UserCredential.class);

        // 自动判断登录类型
        String identifier = userCredential.getCredential();
        if (identifier.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$")) {
            userCredential.setLoginType(LoginType.EMAIL);
        } else if (identifier.matches("^1[3-9]\\d{9}$")) {
            userCredential.setLoginType(LoginType.PHONE);
        } else {
            userCredential.setLoginType(LoginType.USERNAME);
        }

        return userCredential;
    }
}
